package com.mini.dubbo.consumer;

import com.mini.dubbo.consumer.discovery.IServiceDiscovery;
import com.mini.dubbo.core.netty.NettyClient;
import com.mini.dubbo.core.netty.Request;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * Created by yzy on 2018/11/6.
 */
public class RpcClientProxy {
    IServiceDiscovery serviceDiscovery;
    public RpcClientProxy(IServiceDiscovery serviceDiscovery) {
        this.serviceDiscovery = serviceDiscovery;
    }

    public <T> T create(final Class<T> interfaceClazz) {
         return (T) Proxy.newProxyInstance(interfaceClazz.getClassLoader(),
                 new Class<?>[]{interfaceClazz}, new MyInvocationHandler(interfaceClazz));

    }

    class MyInvocationHandler<T> implements InvocationHandler{

        private Class<T> interfaceClazz;

        public MyInvocationHandler(Class<T> interfaceClazz) {
            this.interfaceClazz = interfaceClazz;
        }

        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            Request request = new Request();
            request.setClassName(interfaceClazz.getName());
            request.setMethodName(method.getName());
            request.setTypes(method.getParameterTypes());
            request.setParams(args);

            String url = serviceDiscovery.discover(interfaceClazz.getName());

            NettyClient nettyClient = new NettyClient();
            String ip = url.split(":")[0];
            String port = url.split(":")[1];

            return nettyClient.send(Integer.parseInt(port),ip,request);
        }
    }
}
